﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Eco.ObjectRepresentation;

namespace CommandGraph.Model
{
    /// <summary>
    /// Редактор переменных графа.
    /// Позволяет добавлять, удалять, изменять значения полей
    /// </summary>
    public partial class VariablesEditorForm : Form
    {
        private IList<GraphVariable> variables = new List<GraphVariable>();
        
        /// <summary>
        /// Переменные, редактирование которых ведётся
        /// </summary>
        public IList<GraphVariable> Variables
        {
            get
            {
                return variables;
            }
            set
            {
                variables = value;
                RefreshContent();
            }
        }
        /// <summary>
        /// ECO сервис центр, используемый для создания переменных
        /// </summary>
        public IEcoServiceProvider ServiceProvider { get; set; }

        public VariablesEditorForm()
        {
            InitializeComponent();
        }

        #region Private methods

        private void RefreshContent()
        {
            variablesDGV.Rows.Clear();
            foreach (var variable in variables)
                AddRowForVariable(variable);
        }

        private void AddRowForVariable(GraphVariable variable)
        {
            var newRow = new DataGridViewRow();
            newRow.CreateCells(variablesDGV);
            newRow.Tag = variable;
            newRow.Cells[0].Value = variable.Name;
            newRow.Cells[1].Value = variable.Comment;

            variablesDGV.Rows.Add(newRow);
        }

        private GraphVariable CreateVariable()
        {
            var newVar = new GraphVariable(ServiceProvider);
            newVar.Name = "var_" + variables.Aggregate(0, (acc, var) =>
            {
                if (var.Name == "var_" + acc.ToString())
                    return acc + 1;
                else
                    return acc;
            });
            newVar.Comment = "Newly created variable";
            variables.Add(newVar);
            return newVar;
        }

        private void FillTag(DataGridViewCellEventArgs e)
        {
            var newVar = CreateVariable();
            variablesDGV.Rows[e.RowIndex].Tag = newVar;
            if (string.IsNullOrEmpty(variablesDGV.Rows[e.RowIndex].Cells["nameColumn"].Value as string))
                variablesDGV.Rows[e.RowIndex].Cells["nameColumn"].Value = newVar.Name;
            if (string.IsNullOrEmpty(variablesDGV.Rows[e.RowIndex].Cells["commentColumn"].Value as string))
                variablesDGV.Rows[e.RowIndex].Cells["commentColumn"].Value = newVar.Comment;
        }

        #endregion

        #region Event handlers
		
        private void variablesDGV_CellValidated(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex == (variablesDGV.Rows.Count - 1))
                return;
            if (variablesDGV.Rows[e.RowIndex].Tag == null)
            {
                FillTag(e);
            }
            switch(e.ColumnIndex)
            {
                case 0: 
                    (variablesDGV.Rows[e.RowIndex].Tag as GraphVariable).Name = 
                        variablesDGV.Rows[e.RowIndex].Cells[e.ColumnIndex].Value as string;
                    break;
                case 1:
                    (variablesDGV.Rows[e.RowIndex].Tag as GraphVariable).Comment =
                        variablesDGV.Rows[e.RowIndex].Cells[e.ColumnIndex].Value as string;
                    break;
            }
        }

        private void variablesDGV_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
        {
            if (e.ColumnIndex == 0)
                e.Cancel = variables.Any(var =>
                    (var.Name == (string)e.FormattedValue) && (var != variablesDGV.Rows[e.RowIndex].Tag));
        }

        private void addButton_Click(object sender, EventArgs e)
        {
            AddRowForVariable(CreateVariable());
        }

        private void delButton_Click(object sender, EventArgs e)
        {
            var rowsToDelete = new List<DataGridViewRow>();
            foreach (var cell in variablesDGV.SelectedCells)
            {
                var row = variablesDGV.Rows[(cell as DataGridViewCell).RowIndex];
                if (!rowsToDelete.Contains(row))
                    rowsToDelete.Add(row);
            }

            var lastRow = variablesDGV.Rows[variablesDGV.Rows.Count - 1];
            if (rowsToDelete.Contains(lastRow))
                rowsToDelete.Remove(lastRow);

            foreach (var row in rowsToDelete)
            {
                variables.Remove(row.Tag as GraphVariable);
                variablesDGV.Rows.Remove(row);
            }
        }

        private void VariablesEditorForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            var currentCell = variablesDGV.CurrentCell;
            var currentRow = variablesDGV.Rows[currentCell.RowIndex];

            if (currentRow.Tag == null)
            {
                FillTag(new DataGridViewCellEventArgs(currentCell.ColumnIndex,
                    currentCell.RowIndex));
            }
        }

    	#endregion



    }
}
